﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Mbs.Net
{
    public class PacketParser
    {
        const int defaultBufferSize = 1024 * 100;
        private List<byte> buffer = new List<byte>(defaultBufferSize);
        private readonly byte[] EOF = null;
        private List<byte> packet = new List<byte>(defaultBufferSize);
        private Action<byte[]> onReadyPacket;
        private bool IsFullPacketFlag = true;
        private volatile object innerLock = new object();

        public PacketParser(byte[] packetSeparateFlag, Action<byte[]> callback)
        {
            EOF = packetSeparateFlag;
            onReadyPacket = callback;
        }

        public void Parse(byte[] bytes)
        {
            //lock (innerLock)
            {
                buffer.AddRange(bytes);
                if (buffer.Count < EOF.Length)
                    return;

                int length = buffer.Count;
                int seperateLength = EOF.Length;

                int m = length - seperateLength;
                for (int n = 0; n < seperateLength; n++, m++)
                {
                    if (buffer[m] != EOF[n])
                    {
                        IsFullPacketFlag = false;
                        break;
                    }
                }

                int i = 0;
                for (; i < length; i++)
                {
                    if (packet.Count > 0
                        && buffer[i] == EOF[0]
                        && (i + seperateLength - 1) < length)
                    {
                        bool hasPass = true;
                        for (int j = 1; j < seperateLength; j++)
                        {
                            if (buffer[i + j] != EOF[j])
                            {
                                hasPass = false;
                                break;
                            }
                        }
                        if (!hasPass)
                        {
                            packet.Add(buffer[i]);
                        }
                        else
                        {
                            i += seperateLength - 1;
                            if (onReadyPacket != null)
                                onReadyPacket(packet.ToArray());
                            packet.Clear();
                        }
                    }
                    else
                    {
                        packet.Add(buffer[i]);
                    }

                }

                if (IsFullPacketFlag)
                {
                    buffer.Clear();
                    packet.Clear();
                }
                else
                {
                    buffer.RemoveRange(0, i);
                }
            }
        }
    }
}
